// stm32l011 low level header file
// No guarantees or claims of suitability,reliability or safety of any kind are implied or given
// All the values below were taken from the STM32F030xx reference manual (RM0377)
// Also include macros for enabling and disabling global interrupts
// Written by Frank Duignan
// stm32f011.h
// Latest version of this file can be found at http://eleceng.dit.ie/frank/arm
// Changelog
// First written: 27/07/16

#include <stdint.h>
#define BIT0 (1 << 0)
#define BIT1 (1 << 1)
#define BIT2 (1 << 2)
#define BIT3 (1 << 3)
#define BIT4 (1 << 4)
#define BIT5 (1 << 5)
#define BIT6 (1 << 6)
#define BIT7 (1 << 7)
#define BIT8 (1 << 8)
#define BIT9 (1 << 9)
#define BIT10 (1 << 10)
#define BIT11 (1 << 11)
#define BIT12 (1 << 12)
#define BIT13 (1 << 13)
#define BIT14 (1 << 14)
#define BIT15 (1 << 15)
#define BIT16 (1 << 16)
#define BIT17 (1 << 17)
#define BIT18 (1 << 18)
#define BIT19 (1 << 19)
#define BIT20 (1 << 20)
#define BIT21 (1 << 21)
#define BIT22 (1 << 22)
#define BIT23 (1 << 23)
#define BIT24 (1 << 24)
#define BIT25 (1 << 25)
#define BIT26 (1 << 26)
#define BIT27 (1 << 27)
#define BIT28 (1 << 28)
#define BIT29 (1 << 29)
#define BIT30 (1 << 30)
#define BIT31 (1 << 31)

// Macros to reduce typing later on
#define  REGISTER_32(ADDRESS) (*((volatile uint32_t *)(ADDRESS)))
#define  REGISTER_16(ADDRESS) (*((volatile uint16_t *)(ADDRESS)))
#define  REGISTER_8(ADDRESS) (*((volatile uint8_t *)(ADDRESS)))

// Macros to enable/disable global interrupts
#define enable_interrupts() asm(" cpsie i ")
#define disable_interrupts() asm(" cpsid i ")
#define cpu_sleep() asm(" wfi ")

// Boundary addresses for peripherals
#define GPIOH_BASE	0x50001c00
#define GPIOE_BASE	0x50001000
#define GPIOD_BASE	0x50000c00
#define GPIOC_BASE	0x50000800
#define GPIOB_BASE	0x50000400
#define GPIOA_BASE	0x50000000
#define AES_BASE        0x40026000
#define CRC_BASE	0x40023000
#define FLASH_BASE	0x40022000
#define RCC_BASE	0x40021000
#define DMA_BASE	0x40020000
#define DBGMCU_BASE	0x40015800
#define USART1_BASE	0x40013800
#define SPI1_BASE	0x40013000
#define ADC_BASE	0x40012400
#define FIREWALL_BASE	0x40011c00
#define TIM22_BASE	0x40011400
#define TIM21_BASE	0x40010800
#define EXTI_BASE	0x40010400
#define SYSCFG_BASE	0x40010000
#define LPTIM1_BASE	0x40007c00
#define I2C3_BASE	0x40007800
#define PWR_BASE	0x40007000
#define I2C2_BASE	0x40005800
#define I2C1_BASE	0x40005400
#define USART5_BASE	0x40005000
#define USART4_BASE	0x40004c00
#define LPUART_BASE	0x40004800
#define USART2_BASE	0x40004400
#define SPI2_BASE	0x40003800
#define IWDG_BASE	0x40003000
#define WWDG_BASE	0x40002c00
#define RTC_BASE	0x40002800
#define TIM7_BASE	0x40001400
#define TIM6_BASE	0x40001000
#define TIM3_BASE	0x40000400
#define TIM2_BASE	0x40000000

// GPIO registers 
// PORT A
#define GPIOA_MODER	REGISTER_32(GPIOA_BASE + 0)
#define GPIOA_OTYPER	REGISTER_32(GPIOA_BASE + 4)
#define GPIOA_OSPEEDR	REGISTER_32(GPIOA_BASE + 8)
#define GPIOA_PUPDR	REGISTER_32(GPIOA_BASE + 0x0c)
#define GPIOA_IDR	REGISTER_32(GPIOA_BASE + 0x10)
#define GPIOA_ODR	REGISTER_32(GPIOA_BASE + 0x14)
#define GPIOA_BSRR	REGISTER_32(GPIOA_BASE + 0x18)
#define GPIOA_LCKR	REGISTER_32(GPIOA_BASE + 0x1c)
#define GPIOA_AFRL	REGISTER_32(GPIOA_BASE + 0x20)
#define GPIOA_AFRH	REGISTER_32(GPIOA_BASE + 0x24)
#define GPIOA_BRR	REGISTER_32(GPIOA_BASE + 0x28)

// PORT B
#define GPIOB_MODER	REGISTER_32(GPIOB_BASE + 0)
#define GPIOB_OTYPER	REGISTER_32(GPIOB_BASE + 4)
#define GPIOB_OSPEEDR	REGISTER_32(GPIOB_BASE + 8)
#define GPIOB_PUPDR	REGISTER_32(GPIOB_BASE + 0x0c)
#define GPIOB_IDR	REGISTER_32(GPIOB_BASE + 0x10)
#define GPIOB_ODR	REGISTER_32(GPIOB_BASE + 0x14)
#define GPIOB_BSRR	REGISTER_32(GPIOB_BASE + 0x18)
#define GPIOB_LCKR	REGISTER_32(GPIOB_BASE + 0x1c)
#define GPIOB_AFRL	REGISTER_32(GPIOB_BASE + 0x20)
#define GPIOB_AFRH	REGISTER_32(GPIOB_BASE + 0x24)
#define GPIOB_BRR	REGISTER_32(GPIOB_BASE + 0x28)

// PORT C
#define GPIOC_MODER	REGISTER_32(GPIOC_BASE + 0)
#define GPIOC_OTYPER	REGISTER_32(GPIOC_BASE + 4)
#define GPIOC_OSPEEDR	REGISTER_32(GPIOC_BASE + 8)
#define GPIOC_PUPDR	REGISTER_32(GPIOC_BASE + 0x0c)
#define GPIOC_IDR	REGISTER_32(GPIOC_BASE + 0x10)
#define GPIOC_ODR	REGISTER_32(GPIOC_BASE + 0x14)
#define GPIOC_BSRR	REGISTER_32(GPIOC_BASE + 0x18)
#define GPIOC_LCKR	REGISTER_32(GPIOC_BASE + 0x1c)
#define GPIOC_AFRL	REGISTER_32(GPIOC_BASE + 0x20)
#define GPIOC_AFRH	REGISTER_32(GPIOC_BASE + 0x24)
#define GPIOC_BRR	REGISTER_32(GPIOC_BASE + 0x28)

// PORT D
#define GPIOD_MODER	REGISTER_32(GPIOD_BASE + 0)
#define GPIOD_OTYPER	REGISTER_32(GPIOD_BASE + 4)
#define GPIOD_OSPEEDR	REGISTER_32(GPIOD_BASE + 8)
#define GPIOD_PUPDR	REGISTER_32(GPIOD_BASE + 0x0c)
#define GPIOD_IDR	REGISTER_32(GPIOD_BASE + 0x10)
#define GPIOD_ODR	REGISTER_32(GPIOD_BASE + 0x14)
#define GPIOD_BSRR	REGISTER_32(GPIOD_BASE + 0x18)
#define GPIOD_LCKR	REGISTER_32(GPIOD_BASE + 0x1c)
#define GPIOD_AFRL	REGISTER_32(GPIOD_BASE + 0x20)
#define GPIOD_AFRH	REGISTER_32(GPIOD_BASE + 0x24)
#define GPIOD_BRR	REGISTER_32(GPIOD_BASE + 0x28)

// PORT E
#define GPIOE_MODER	REGISTER_32(GPIOE_BASE + 0)
#define GPIOE_OTYPER	REGISTER_32(GPIOE_BASE + 4)
#define GPIOE_OSPEEDR	REGISTER_32(GPIOE_BASE + 8)
#define GPIOE_PUPDR	REGISTER_32(GPIOE_BASE + 0x0c)
#define GPIOE_IDR	REGISTER_32(GPIOE_BASE + 0x10)
#define GPIOE_ODR	REGISTER_32(GPIOE_BASE + 0x14)
#define GPIOE_BSRR	REGISTER_32(GPIOE_BASE + 0x18)
#define GPIOE_LCKR	REGISTER_32(GPIOE_BASE + 0x1c)
#define GPIOE_AFRL	REGISTER_32(GPIOE_BASE + 0x20)
#define GPIOE_AFRH	REGISTER_32(GPIOE_BASE + 0x24)
#define GPIOE_BRR	REGISTER_32(GPIOE_BASE + 0x28)


// PORT H
#define GPIOH_MODER	REGISTER_32(GPIOH_BASE + 0)
#define GPIOH_OTYPER	REGISTER_32(GPIOH_BASE + 4)
#define GPIOH_OSPEEDR	REGISTER_32(GPIOH_BASE + 8)
#define GPIOH_PUPDR	REGISTER_32(GPIOH_BASE + 0x0c)
#define GPIOH_IDR	REGISTER_32(GPIOH_BASE + 0x10)
#define GPIOH_ODR	REGISTER_32(GPIOH_BASE + 0x14)
#define GPIOH_BSRR	REGISTER_32(GPIOH_BASE + 0x18)
#define GPIOH_LCKR	REGISTER_32(GPIOH_BASE + 0x1c)
#define GPIOH_AFRL	REGISTER_32(GPIOH_BASE + 0x20)
#define GPIOH_AFRH	REGISTER_32(GPIOH_BASE + 0x24)
#define GPIOH_BRR	REGISTER_32(GPIOH_BASE + 0x28)


// AES
#define AES_CR  	REGISTER_32(AES_BASE + 0x0000)
#define AES_SR  	REGISTER_32(AES_BASE + 0x0004)
#define AES_DINR  	REGISTER_32(AES_BASE + 0x0008)
#define AES_DOUTR  	REGISTER_32(AES_BASE + 0x000c)
#define AES_KEYR0  	REGISTER_32(AES_BASE + 0x0010)
#define AES_KEYR1  	REGISTER_32(AES_BASE + 0x0014)
#define AES_KEYR2  	REGISTER_32(AES_BASE + 0x0018)
#define AES_KEYR3  	REGISTER_32(AES_BASE + 0x001c)
#define AES_IVR0  	REGISTER_32(AES_BASE + 0x0020)
#define AES_IVR1  	REGISTER_32(AES_BASE + 0x0024)
#define AES_IVR2  	REGISTER_32(AES_BASE + 0x0028)
#define AES_IVR3  	REGISTER_32(AES_BASE + 0x002c)



// CRC
#define CRC_DR 		REGISTER_32(CRC_BASE + 0)
#define CRC_IDR 	REGISTER_32(CRC_BASE + 4)
#define CRC_CR 		REGISTER_32(CRC_BASE + 8)
#define CRC_INIT 	REGISTER_32(CRC_BASE + 0x10)
#define CRC_POL 	REGISTER_32(CRC_BASE + 0x14)

// FLASH
#define FLASH_ACR	REGISTER_32(FLASH_BASE + 0)
#define FLASH_PECR	REGISTER_32(FLASH_BASE + 4)
#define FLASH_PDKEYR	REGISTER_32(FLASH_BASE + 8)
#define FLASH_PKEYR	REGISTER_32(FLASH_BASE + 0x0c)
#define FLASH_PRGKEYR	REGISTER_32(FLASH_BASE + 0x10)
#define FLASH_OPTKEYR	REGISTER_32(FLASH_BASE + 0x14)
#define FLASH_SR	REGISTER_32(FLASH_BASE + 0x18)
#define FLASH_OPTR	REGISTER_32(FLASH_BASE + 0x1c)
#define FLASH_WRPROT1	REGISTER_32(FLASH_BASE + 0x20)
#define FLASH_WRPROT2	REGISTER_32(FLASH_BASE + 0x80)

// RCC registers
#define RCC_CR 		REGISTER_32(RCC_BASE + 0)
#define RCC_ICSCR	REGISTER_32(RCC_BASE + 4)
#define RCC_CFGR	REGISTER_32(RCC_BASE + 0x0c)
#define RCC_CIER	REGISTER_32(RCC_BASE + 0x10)	
#define RCC_CIFR	REGISTER_32(RCC_BASE + 0x14)	
#define RCC_CICR	REGISTER_32(RCC_BASE + 0x18)
#define RCC_IOPRSTR	REGISTER_32(RCC_BASE + 0x1c)
#define RCC_AHBRSTR	REGISTER_32(RCC_BASE + 0x20)
#define RCC_APB2RSTR	REGISTER_32(RCC_BASE + 0x24)
#define RCC_APB1RSTR	REGISTER_32(RCC_BASE + 0x28)
#define RCC_IOPENR	REGISTER_32(RCC_BASE + 0x2c)
#define RCC_AHBENR	REGISTER_32(RCC_BASE + 0x30)
#define RCC_APB2ENR	REGISTER_32(RCC_BASE + 0x34)
#define RCC_APB1ENR	REGISTER_32(RCC_BASE + 0x38)
#define RCC_IOPSMEM	REGISTER_32(RCC_BASE + 0x3c)
#define RCC_AHBSMENR	REGISTER_32(RCC_BASE + 0x40)
#define RCC_APB2SMENR	REGISTER_32(RCC_BASE + 0x44)
#define RCC_APB1SMENR	REGISTER_32(RCC_BASE + 0x48)
#define RCC_CCIPR	REGISTER_32(RCC_BASE + 0x4c)
#define RCC_CSR 	REGISTER_32(RCC_BASE + 0x50)

// DMA
#define DMA_ISR 	REGISTER_32(DMA_BASE + 0)
#define DMA_IFCR 	REGISTER_32(DMA_BASE + 4)
#define DMA_CCR1 	REGISTER_32(DMA_BASE + 8)
#define DMA_CNDTR1	REGISTER_32(DMA_BASE + 0x0c)
#define DMA_CPAR1	REGISTER_32(DMA_BASE + 0x10)
#define DMA_CMAR1	REGISTER_32(DMA_BASE + 0x14)
#define DMA_CCR2	REGISTER_32(DMA_BASE + 0x1c)
#define DMA_CNDTR2	REGISTER_32(DMA_BASE + 0x20)
#define DMA_CPAR2	REGISTER_32(DMA_BASE + 0x24)
#define DMA_CMAR2	REGISTER_32(DMA_BASE + 0x28)
#define DMA_CCR3	REGISTER_32(DMA_BASE + 0x30)
#define DMA_CNDTR3	REGISTER_32(DMA_BASE + 0x34)
#define DMA_CPAR3	REGISTER_32(DMA_BASE + 0x38)
#define DMA_CMAR3	REGISTER_32(DMA_BASE + 0x3c)
#define DMA_CCR4	REGISTER_32(DMA_BASE + 0x44)
#define DMA_CNDTR4	REGISTER_32(DMA_BASE + 0x48)
#define DMA_CPAR4	REGISTER_32(DMA_BASE + 0x4c)
#define DMA_CMAR4	REGISTER_32(DMA_BASE + 0x50)
#define DMA_CCR5	REGISTER_32(DMA_BASE + 0x58)
#define DMA_CNDTR5	REGISTER_32(DMA_BASE + 0x5c)
#define DMA_CPAR5	REGISTER_32(DMA_BASE + 0x60)
#define DMA_CMAR5	REGISTER_32(DMA_BASE + 0x64)
#define DMA_CCR6	REGISTER_32(DMA_BASE + 0x6c)
#define DMA_CNDTR6	REGISTER_32(DMA_BASE + 0x70)
#define DMA_CPAR6	REGISTER_32(DMA_BASE + 0x74)
#define DMA_CMAR6	REGISTER_32(DMA_BASE + 0x78)
#define DMA_CCR7	REGISTER_32(DMA_BASE + 0x80)
#define DMA_CNDTR7	REGISTER_32(DMA_BASE + 0x84)
#define DMA_CPAR7	REGISTER_32(DMA_BASE + 0x88)
#define DMA_CMAR7	REGISTER_32(DMA_BASE + 0x8c)
#define DMA_CSELR	REGISTER_32(DMA_BASE + 0xa8)

// DBGMCU
#define DBG_IDCODE	REGISTER_32(DBGMCU_BASE + 0x0)
#define DBG_CR  	REGISTER_32(DBGMCU_BASE + 0x4)
#define DBG_APB1_FZ  	REGISTER_32(DBGMCU_BASE + 0x8)
#define DBG_APB2_FZ  	REGISTER_32(DBGMCU_BASE + 0xc)


// USART1

#define USART1_CR1	REGISTER_32(USART1_BASE + 0)
#define USART1_CR2	REGISTER_32(USART1_BASE + 4)
#define USART1_CR3	REGISTER_32(USART1_BASE + 8)
#define USART1_BRR	REGISTER_32(USART1_BASE + 0x0c)
#define USART1_GTPR	REGISTER_32(USART1_BASE + 0x10)
#define USART1_RTOR	REGISTER_32(USART1_BASE + 0x14)
#define USART1_RQR	REGISTER_32(USART1_BASE + 0x18)
#define USART1_ISR	REGISTER_32(USART1_BASE + 0x1c)
#define USART1_ICR	REGISTER_32(USART1_BASE + 0x20)
#define USART1_RDR	REGISTER_32(USART1_BASE + 0x24)
#define USART1_TDR	REGISTER_32(USART1_BASE + 0x28)


// SPI1
#define SPI1_CR1	REGISTER_32(SPI1_BASE + 0)
#define SPI1_CR2	REGISTER_32(SPI1_BASE + 4)
#define SPI1_SR		REGISTER_32(SPI1_BASE + 8)
#define SPI1_DR		REGISTER_16(SPI1_BASE + 0x0c)
#define SPI1_DR8	REGISTER_8(SPI1_BASE + 0x0c)
#define SPI1_CRCPR	REGISTER_32(SPI1_BASE + 0x10)
#define SPI1_RXCRCR	REGISTER_32(SPI1_BASE + 0x14)
#define SPI1_TXCRCR	REGISTER_32(SPI1_BASE + 0x18)
#define SPI1_I2SCFGR	REGISTER_32(SPI1_BASE + 0x1c)
#define SPI1_I2SPR	REGISTER_32(SPI1_BASE + 0x20)


// ADC
#define ADC_ISR		REGISTER_32(ADC_BASE + 0)
#define ADC_IER		REGISTER_32(ADC_BASE + 4)
#define ADC_CR		REGISTER_32(ADC_BASE + 8)
#define ADC_CFGR1	REGISTER_32(ADC_BASE + 0x0c)
#define ADC_CFGR2	REGISTER_32(ADC_BASE + 0x10)
#define ADC_SMPR	REGISTER_32(ADC_BASE + 0x14)
#define ADC_TR		REGISTER_32(ADC_BASE + 0x20)
#define ADC_CHSELR	REGISTER_32(ADC_BASE + 0x28)
#define ADC_DR		REGISTER_32(ADC_BASE + 0x40)
#define ADC_CCR		REGISTER_32(ADC_BASE + 0x308)

// FIREWALL
#define FW_CSSA 	REGISTER_32(FIREWALL_BASE + 0x00)
#define FW_CSL  	REGISTER_32(FIREWALL_BASE + 0x04)
#define FW_NVDSSA  	REGISTER_32(FIREWALL_BASE + 0x08)
#define FW_NVDSL  	REGISTER_32(FIREWALL_BASE + 0x0c)
#define FW_VDSSA  	REGISTER_32(FIREWALL_BASE + 0x10)
#define FW_VDSL  	REGISTER_32(FIREWALL_BASE + 0x14)
#define FW_CR     	REGISTER_32(FIREWALL_BASE + 0x20)


 
// Timer 22
#define TIM22_CR1	REGISTER_32(TIM22_BASE + 0)
#define TIM22_CR2	REGISTER_32(TIM22_BASE + 4)
#define TIM22_SMCR	REGISTER_32(TIM22_BASE + 0x08)
#define TIM22_DIER	REGISTER_32(TIM22_BASE + 0x0c)
#define TIM22_SR	REGISTER_32(TIM22_BASE + 0x10)
#define TIM22_EGR	REGISTER_32(TIM22_BASE + 0x14)
#define TIM22_CCMR1	REGISTER_32(TIM22_BASE + 0x18)
#define TIM22_CCER	REGISTER_32(TIM22_BASE + 0x20)
#define TIM22_CNT	REGISTER_32(TIM22_BASE + 0x24)
#define TIM22_PSC	REGISTER_32(TIM22_BASE + 0x28)
#define TIM22_ARR	REGISTER_32(TIM22_BASE + 0x2c)
#define TIM22_CCR1	REGISTER_32(TIM22_BASE + 0x34)
#define TIM22_CCR2	REGISTER_32(TIM22_BASE + 0x38)
#define TIM22_OR	REGISTER_32(TIM22_BASE + 0x50)

 
// Timer 21
#define TIM21_CR1	REGISTER_32(TIM21_BASE + 0)
#define TIM21_CR2	REGISTER_32(TIM21_BASE + 4)
#define TIM21_SMCR	REGISTER_32(TIM21_BASE + 0x08)
#define TIM21_DIER	REGISTER_32(TIM21_BASE + 0x0c)
#define TIM21_SR	REGISTER_32(TIM21_BASE + 0x10)
#define TIM21_EGR	REGISTER_32(TIM21_BASE + 0x14)
#define TIM21_CCMR1	REGISTER_32(TIM21_BASE + 0x18)
#define TIM21_CCER	REGISTER_32(TIM21_BASE + 0x20)
#define TIM21_CNT	REGISTER_32(TIM21_BASE + 0x24)
#define TIM21_PSC	REGISTER_32(TIM21_BASE + 0x28)
#define TIM21_ARR	REGISTER_32(TIM21_BASE + 0x2c)
#define TIM21_CCR1	REGISTER_32(TIM21_BASE + 0x34)
#define TIM21_CCR2	REGISTER_32(TIM21_BASE + 0x38)
#define TIM21_OR	REGISTER_32(TIM21_BASE + 0x50)


// EXTI	
#define EXTI_IMR	REGISTER_32(EXTI_BASE + 0)
#define EXTI_EMR	REGISTER_32(EXTI_BASE + 4)
#define EXTI_RTSR	REGISTER_32(EXTI_BASE + 8)
#define EXTI_FTSR	REGISTER_32(EXTI_BASE + 0x0c)
#define EXTI_SWIER	REGISTER_32(EXTI_BASE + 0x10)
#define EXTI_PR		REGISTER_32(EXTI_BASE + 0x14)



// SYS Config
#define SYSCFG_CFGR1	REGISTER_32(SYSCFG_BASE + 0)
#define SYSCFG_CFGR2	REGISTER_32(SYSCFG_BASE + 4)
#define SYSCFG_EXTICR1	REGISTER_32(SYSCFG_BASE + 8)
#define SYSCFG_EXTICR2	REGISTER_32(SYSCFG_BASE + 0x0c)
#define SYSCFG_EXTICR3	REGISTER_32(SYSCFG_BASE + 0x10)
#define SYSCFG_EXTICR4	REGISTER_32(SYSCFG_BASE + 0x14)
#define COMP1_CTRL	REGISTER_32(SYSCFG_BASE + 0x18)
#define COMP2_CTRL	REGISTER_32(SYSCFG_BASE + 0x1c)
#define SYSCFG_CFGR3	REGISTER_32(SYSCFG_BASE + 0x20)

// LPTIM1
#define LPTIM1_ISR	REGISTER_32(SYSCFG_BASE + 0x00)
#define LPTIM1_ICR	REGISTER_32(SYSCFG_BASE + 0x04)
#define LPTIM1_IER	REGISTER_32(SYSCFG_BASE + 0x08)
#define LPTIM1_CFGR	REGISTER_32(SYSCFG_BASE + 0x0c)
#define LPTIM1_CR	REGISTER_32(SYSCFG_BASE + 0x10)
#define LPTIM1_CMP	REGISTER_32(SYSCFG_BASE + 0x14)
#define LPTIM1_ARR	REGISTER_32(SYSCFG_BASE + 0x18)
#define LPTIM1_CNT	REGISTER_32(SYSCFG_BASE + 0x1c)

// I2C3
#define I2C3_CR1	REGISTER_32(I2C3_BASE + 0)
#define I2C3_CR2	REGISTER_32(I2C3_BASE + 4)
#define I2C3_OAR1	REGISTER_32(I2C3_BASE + 8)
#define I2C3_OAR2	REGISTER_32(I2C3_BASE + 0x0c)
#define I2C3_TIMINGR	REGISTER_32(I2C3_BASE + 0x10)
#define I2C3_TIMEOUTR	REGISTER_32(I2C3_BASE + 0x14)
#define I2C3_ISR	REGISTER_32(I2C3_BASE + 0x18)
#define I2C3_ICR	REGISTER_32(I2C3_BASE + 0x1c)
#define I2C3_PECR	REGISTER_32(I2C3_BASE + 0x20)
#define I2C3_RXDR	REGISTER_8(I2C3_BASE + 0x24)
#define I2C3_TXDR	REGISTER_8(I2C3_BASE + 0x28)


// PWR 
#define PWR_CR		REGISTER_32(PWR_BASE + 0x00)
#define PWR_CSR		REGISTER_32(PWR_BASE + 0x04)

// I2C2
#define I2C2_CR1	REGISTER_32(I2C2_BASE + 0)
#define I2C2_CR2	REGISTER_32(I2C2_BASE + 4)
#define I2C2_OAR1	REGISTER_32(I2C2_BASE + 8)
#define I2C2_OAR2	REGISTER_32(I2C2_BASE + 0x0c)
#define I2C2_TIMINGR	REGISTER_32(I2C2_BASE + 0x10)
#define I2C2_TIMEOUTR	REGISTER_32(I2C2_BASE + 0x14)
#define I2C2_ISR	REGISTER_32(I2C2_BASE + 0x18)
#define I2C2_ICR	REGISTER_32(I2C2_BASE + 0x1c)
#define I2C2_PECR	REGISTER_32(I2C2_BASE + 0x20)
#define I2C2_RXDR	REGISTER_8(I2C2_BASE + 0x24)
#define I2C2_TXDR	REGISTER_8(I2C2_BASE + 0x28)

// I2C1
#define I2C1_CR1	REGISTER_32(I2C1_BASE + 0)
#define I2C1_CR2	REGISTER_32(I2C1_BASE + 4)
#define I2C1_OAR1	REGISTER_32(I2C1_BASE + 8)
#define I2C1_OAR2	REGISTER_32(I2C1_BASE + 0x0c)
#define I2C1_TIMINGR	REGISTER_32(I2C1_BASE + 0x10)
#define I2C1_TIMEOUTR	REGISTER_32(I2C1_BASE + 0x14)
#define I2C1_ISR	REGISTER_32(I2C1_BASE + 0x18)
#define I2C1_ICR	REGISTER_32(I2C1_BASE + 0x1c)
#define I2C1_PECR	REGISTER_32(I2C1_BASE + 0x20)
#define I2C1_RXDR	REGISTER_8(I2C1_BASE + 0x24)
#define I2C1_TXDR	REGISTER_8(I2C1_BASE + 0x28)


// USART5

#define USART5_CR1	REGISTER_32(USART5_BASE + 0)
#define USART5_CR2	REGISTER_32(USART5_BASE + 4)
#define USART5_CR3	REGISTER_32(USART5_BASE + 8)
#define USART5_BRR	REGISTER_32(USART5_BASE + 0x0c)
#define USART5_GTPR	REGISTER_32(USART5_BASE + 0x10)
#define USART5_RTOR	REGISTER_32(USART5_BASE + 0x14)
#define USART5_RQR	REGISTER_32(USART5_BASE + 0x18)
#define USART5_ISR	REGISTER_32(USART5_BASE + 0x1c)
#define USART5_ICR	REGISTER_32(USART5_BASE + 0x20)
#define USART5_RDR	REGISTER_32(USART5_BASE + 0x24)
#define USART5_TDR	REGISTER_32(USART5_BASE + 0x28)

// USART4


#define USART4_CR1	REGISTER_32(USART4_BASE + 0)
#define USART4_CR2	REGISTER_32(USART4_BASE + 4)
#define USART4_CR3	REGISTER_32(USART4_BASE + 8)
#define USART4_BRR	REGISTER_32(USART4_BASE + 0x0c)
#define USART4_GTPR	REGISTER_32(USART4_BASE + 0x10)
#define USART4_RTOR	REGISTER_32(USART4_BASE + 0x14)
#define USART4_RQR	REGISTER_32(USART4_BASE + 0x18)
#define USART4_ISR	REGISTER_32(USART4_BASE + 0x1c)
#define USART4_ICR	REGISTER_32(USART4_BASE + 0x20)
#define USART4_RDR	REGISTER_32(USART4_BASE + 0x24)
#define USART4_TDR	REGISTER_32(USART4_BASE + 0x28)

// LPUART 
#define LPUART_CR1	REGISTER_32(LPUART_BASE + 0)
#define LPUART_CR2	REGISTER_32(LPUART_BASE + 4)
#define LPUART_CR3	REGISTER_32(LPUART_BASE + 8)
#define LPUART_BRR	REGISTER_32(LPUART_BASE + 0x0c)
#define LPUART_RQR	REGISTER_32(LPUART_BASE + 0x18)
#define LPUART_ISR	REGISTER_32(LPUART_BASE + 0x1c)
#define LPUART_ICR	REGISTER_32(LPUART_BASE + 0x20)
#define LPUART_RDR	REGISTER_32(LPUART_BASE + 0x24)
#define LPUART_TDR	REGISTER_32(LPUART_BASE + 0x28)

// USART2
#define USART2_CR1	REGISTER_32(USART2_BASE + 0)
#define USART2_CR2	REGISTER_32(USART2_BASE + 4)
#define USART2_CR3	REGISTER_32(USART2_BASE + 8)
#define USART2_BRR	REGISTER_32(USART2_BASE + 0x0c)
#define USART2_GTPR	REGISTER_32(USART2_BASE + 0x10)
#define USART2_RTOR	REGISTER_32(USART2_BASE + 0x14)
#define USART2_RQR	REGISTER_32(USART2_BASE + 0x18)
#define USART2_ISR	REGISTER_32(USART2_BASE + 0x1c)
#define USART2_ICR	REGISTER_32(USART2_BASE + 0x20)
#define USART2_RDR	REGISTER_32(USART2_BASE + 0x24)
#define USART2_TDR	REGISTER_32(USART2_BASE + 0x28)


// SPI2
#define SPI2_CR1	REGISTER_32(SPI2_BASE + 0)
#define SPI2_CR2	REGISTER_32(SPI2_BASE + 4)
#define SPI2_SR		REGISTER_32(SPI2_BASE + 8)
#define SPI2_DR		REGISTER_16(SPI2_BASE + 0x0c)
#define SPI1_DR8	REGISTER_8(SPI1_BASE + 0x0c)
#define SPI2_CRCPR	REGISTER_32(SPI2_BASE + 0x10)
#define SPI2_RXCRCR	REGISTER_32(SPI2_BASE + 0x14)
#define SPI2_TXCRCR	REGISTER_32(SPI2_BASE + 0x18)
#define SPI2_I2SCFGR	REGISTER_32(SPI2_BASE + 0x1c)
#define SPI2_I2SPR	REGISTER_32(SPI2_BASE + 0x20)


// IWDG 
#define IWDG_KR 	REGISTER_32(IWDG_BASE + 0x00)
#define IWDG_PR 	REGISTER_32(IWDG_BASE + 0x04)
#define IWDG_RLR 	REGISTER_32(IWDG_BASE + 0x08)
#define IWDG_SR 	REGISTER_32(IWDG_BASE + 0x0c)
#define IWDG_WINR 	REGISTER_32(IWDG_BASE + 0x10)

// WWDG 
#define WWDG_CR 	REGISTER_32(WWDG_BASE + 0x00)
#define WWDG_CFR 	REGISTER_32(WWDG_BASE + 0x04)
#define WWDG_SR 	REGISTER_32(WWDG_BASE + 0x08)


// RTC
#define RTC_TR		REGISTER_32(RTC_BASE + 0x00)
#define RTC_DR		REGISTER_32(RTC_BASE + 0x04)
#define RTC_CR		REGISTER_32(RTC_BASE + 0x08)
#define RTC_ISR		REGISTER_32(RTC_BASE + 0x0c)
#define RTC_PRER	REGISTER_32(RTC_BASE + 0x10)
#define RTC_WUTR	REGISTER_32(RTC_BASE + 0x14)
#define RTC_ALRMAR	REGISTER_32(RTC_BASE + 0x1c)
#define RTC_ALRMBR	REGISTER_32(RTC_BASE + 0x20)
#define RTC_WPR		REGISTER_32(RTC_BASE + 0x24)
#define RTC_SSR		REGISTER_32(RTC_BASE + 0x28)
#define RTC_SHIFTR	REGISTER_32(RTC_BASE + 0x2c)
#define RTC_TSTR	REGISTER_32(RTC_BASE + 0x30)
#define RTC_TSDR	REGISTER_32(RTC_BASE + 0x34)
#define RTC_TSSSR	REGISTER_32(RTC_BASE + 0x38)
#define RTC_CALR	REGISTER_32(RTC_BASE + 0x3c)
#define RTC_TAMPCR	REGISTER_32(RTC_BASE + 0x40)
#define RTC_ALRMASSR	REGISTER_32(RTC_BASE + 0x44)
#define RTC_ALRMBSSR	REGISTER_32(RTC_BASE + 0x48)
#define RTC_OR	        REGISTER_32(RTC_BASE + 0x4c)
#define RTC_BKP0R       REGISTER_32(RTC_BASE + 0x50)
#define RTC_BKP1R       REGISTER_32(RTC_BASE + 0x54)
#define RTC_BKP2R       REGISTER_32(RTC_BASE + 0x58)
#define RTC_BKP3R       REGISTER_32(RTC_BASE + 0x5c)
#define RTC_BKP4R       REGISTER_32(RTC_BASE + 0x60)

// TIM7 
#define TIM7_CR1	REGISTER_32(TIM7_BASE + 0)
#define TIM7_CR2	REGISTER_32(TIM7_BASE + 4)
#define TIM7_DIER	REGISTER_32(TIM7_BASE + 0x0c)
#define TIM7_SR	        REGISTER_32(TIM7_BASE + 0x10)
#define TIM7_EGR	REGISTER_32(TIM7_BASE + 0x14)
#define TIM7_CNT	REGISTER_32(TIM7_BASE + 0x24)
#define TIM7_PSC	REGISTER_32(TIM7_BASE + 0x28)
#define TIM7_ARR	REGISTER_32(TIM7_BASE + 0x2c)

// TIM6 
#define TIM6_CR1	REGISTER_32(TIM6_BASE + 0)
#define TIM6_CR2	REGISTER_32(TIM6_BASE + 4)
#define TIM6_DIER	REGISTER_32(TIM6_BASE + 0x0c)
#define TIM6_SR	        REGISTER_32(TIM6_BASE + 0x10)
#define TIM6_EGR	REGISTER_32(TIM6_BASE + 0x14)
#define TIM6_CNT	REGISTER_32(TIM6_BASE + 0x24)
#define TIM6_PSC	REGISTER_32(TIM6_BASE + 0x28)
#define TIM6_ARR	REGISTER_32(TIM6_BASE + 0x2c)



// TIM3
#define TIM3_CR1	REGISTER_16(TIM3_BASE + 0)
#define TIM3_CR2	REGISTER_16(TIM3_BASE + 4)
#define TIM3_SMCR	REGISTER_16(TIM3_BASE + 8)
#define TIM3_DIER	REGISTER_16(TIM3_BASE + 0x0c)
#define TIM3_SR		REGISTER_16(TIM3_BASE + 0x10)
#define TIM3_EGR	REGISTER_16(TIM3_BASE + 0x14)
#define TIM3_CCMR1	REGISTER_16(TIM3_BASE + 0x18)
#define TIM3_CCMR2	REGISTER_16(TIM3_BASE + 0x1c)
#define TIM3_CCER	REGISTER_16(TIM3_BASE + 0x20)
#define TIM3_CNT	REGISTER_16(TIM3_BASE + 0x24)
#define TIM3_PSC	REGISTER_16(TIM3_BASE + 0x28)
#define TIM3_ARR	REGISTER_16(TIM3_BASE + 0x2c)
#define TIM3_CCR1	REGISTER_16(TIM3_BASE + 0x34)
#define TIM3_CCR2	REGISTER_16(TIM3_BASE + 0x38)
#define TIM3_CCR3	REGISTER_16(TIM3_BASE + 0x3c)
#define TIM3_CCR4	REGISTER_16(TIM3_BASE + 0x40)
#define TIM3_DCR	REGISTER_16(TIM3_BASE + 0x48)
#define TIM3_DMAR	REGISTER_16(TIM3_BASE + 0x4c)
#define TIM3_OR	        REGISTER_16(TIM3_BASE + 0x50)


// TIM2
#define TIM2_CR1	REGISTER_16(TIM2_BASE + 0)
#define TIM2_CR2	REGISTER_16(TIM2_BASE + 4)
#define TIM2_SMCR	REGISTER_16(TIM2_BASE + 8)
#define TIM2_DIER	REGISTER_16(TIM2_BASE + 0x0c)
#define TIM2_SR		REGISTER_16(TIM2_BASE + 0x10)
#define TIM2_EGR	REGISTER_16(TIM2_BASE + 0x14)
#define TIM2_CCMR1	REGISTER_16(TIM2_BASE + 0x18)
#define TIM2_CCMR2	REGISTER_16(TIM2_BASE + 0x1c)
#define TIM2_CCER	REGISTER_16(TIM2_BASE + 0x20)
#define TIM2_CNT	REGISTER_16(TIM2_BASE + 0x24)
#define TIM2_PSC	REGISTER_16(TIM2_BASE + 0x28)
#define TIM2_ARR	REGISTER_16(TIM2_BASE + 0x2c)
#define TIM2_RCR	REGISTER_16(TIM2_BASE + 0x30)
#define TIM2_CCR1	REGISTER_16(TIM2_BASE + 0x34)
#define TIM2_CCR2	REGISTER_16(TIM2_BASE + 0x38)
#define TIM2_CCR3	REGISTER_16(TIM2_BASE + 0x3c)
#define TIM2_CCR4	REGISTER_16(TIM2_BASE + 0x40)
#define TIM2_BDTR	REGISTER_16(TIM2_BASE + 0x44)
#define TIM2_DCR	REGISTER_16(TIM2_BASE + 0x48)
#define TIM2_DMAR	REGISTER_16(TIM2_BASE + 0x4c)
#define TIM2_OR	        REGISTER_16(TIM2_BASE + 0x50)

// Core peripherals
#define STK_BASE	0xe000e010
#define SCB_BASE	0xe0000000
#define NVIC_BASE 	0xe000e100

// Option bytes - see reference manual for details.

#define OPTION_WORD0	REGISTER_32( 0x1fff8000 )
#define OPTION_WORD1	REGISTER_32( 0x1fff8004 )
#define OPTION_WRPROT1_WORD0	REGISTER_32( 0x1fff8008 )
#define OPTION_WRPROT1_WORD1	REGISTER_32( 0x1fff800c )
#define OPTION_WRPROT2_WORD0	REGISTER_32( 0x1fff8010 )

// NVIC
#define ISER		REGISTER_32(NVIC_BASE + 0)
#define ICER		REGISTER_32(NVIC_BASE + 0x80)
#define ISPR		REGISTER_32(NVIC_BASE + 0x100)
#define ICPR		REGISTER_32(NVIC_BASE + 0x180)
#define IPR0		REGISTER_32(NVIC_BASE + 0x300)
#define IPR1		REGISTER_32(NVIC_BASE + 0x304)
#define IPR2		REGISTER_32(NVIC_BASE + 0x308)
#define IPR3		REGISTER_32(NVIC_BASE + 0x30c)
#define IPR4		REGISTER_32(NVIC_BASE + 0x310)
#define IPR5		REGISTER_32(NVIC_BASE + 0x314)
#define IPR6		REGISTER_32(NVIC_BASE + 0x318)
#define IPR7		REGISTER_32(NVIC_BASE + 0x31c)

// STK
#define STK_CSR		REGISTER_32(STK_BASE + 0)
#define STK_RVR		REGISTER_32(STK_BASE + 4)
#define STK_CVR		REGISTER_32(STK_BASE + 8)
#define STK_CALIB	REGISTER_32(STK_BASE + 0x0c)

// SCB
#define ACTLR		REGISTER_32(SCB_BASE + 0xe008)
#define CPUID		REGISTER_32(SCB_BASE + 0xed00)
#define ICSR		REGISTER_32(SCB_BASE + 0xed04)
#define VTOR		REGISTER_32(SCB_BASE + 0xed08)
#define AIRCR		REGISTER_32(SCB_BASE + 0xed0c)
#define SCR		REGISTER_32(SCB_BASE + 0xed10)
#define CCR		REGISTER_32(SCB_BASE + 0xed14)
#define SHPR2		REGISTER_32(SCB_BASE + 0xed1c)
#define SHPR3		REGISTER_32(SCB_BASE + 0xed20)
#define SHCSR		REGISTER_32(SCB_BASE + 0xed24)
#define DFSR		REGISTER_32(SCB_BASE + 0xed30)
